package com.gouwudai.gobbs.dao.impl;

import java.sql.SQLException;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;

import com.gouwudai.gobbs.common.HibernatePageList;
import com.gouwudai.gobbs.common.IPageList;
import com.gouwudai.gobbs.common.JdbcPageList;
import com.litt.core.common.Utility;
import com.litt.core.exception.DBException;

/**
 * 
 * <pre>
 *  Title:DAO基类
 *  Description: 所有DAO的基类，封装了Hibernate和JDBC的数据库操作，隐藏底层的复杂实现  
 * </pre>
 * 
 * @author <a href="mailto:littcai@hotmail.com">空心大白菜</a>
 * @date 2007-3-29
 * @version 1.0
 * <pre>
 * 修改记录
 *    修改后版本:     修改人：  修改日期:     修改内容: 
 * </pre>
 */
public class BaseDAOImpl
{
    
    /**
     * 
     */
    private transient final static Log logger = LogFactory.getLog(BaseDAOImpl.class);
	
	/**
	 * 
	 */
	private HibernateTemplate hibernateTemplate;
	
	/**
	 * 
	 */
	private JdbcTemplate jdbcTemplate;

/* ************************* 封装的Hibernate操作 ******************************** */    
    
	/**
     * 直接执行更新操作的HQL语句.
     * @param hql 需要执行的HQL语句
     */
	protected void executeHql(String hql)
	{
		final String temp = hql;
		hibernateTemplate.execute(new HibernateCallback() {

			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(temp);
				query.executeUpdate();
				return null;
			}
		});

	}
	
	/**
     * 批量执行更新操作的HQL语句，同�1个事务中.
     * @param hql 更新的HQL数组
     */
	protected void executeHql(String[] hql)
	{
		final String[] temp = hql;
		
		hibernateTemplate.execute(new HibernateCallback() {

			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				
				for(int i=0;i<temp.length;i++)
		        {	
					Query query = session.createQuery(temp[i]);
					query.executeUpdate();
		        }				
				return null;
			}
		});
	}
	
	/**
     * 直接执行查询唯一结果HQL语句.
     * @param hql 查询的HQL语句
     * @return Object 对象
     */
	protected Object uniqueResultHql(String hql)
	{
		final String temp = hql;
		return hibernateTemplate.execute(new HibernateCallback() {

			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(temp);
				query.setMaxResults(1);				
				return query.uniqueResult();
			}
		});
	}	
	
	/**
     * 根据主键查找对象.
     * @param className 类
     * @param id 主键值
     * @return Object 对象
     */
	protected Object loadObject(Class className,Integer id)
	{
		return hibernateTemplate.get(className, id); 
	}
	
	/**
     * 根据某个字段查找对象，如果有多个对象的话取第�1个对�象.
     * @param idenityName 字段名称
     * @param className 类名
     * @param id 字段值
     * @return Object 对象
     */
	protected Object loadObject(String className,String idenityName,String id)
	{
		StringBuilder hql = new StringBuilder("from ");
		hql.append(className);
		hql.append(" where ");
		hql.append(idenityName);
		hql.append("='");
		hql.append(id);
		hql.append("'");
		
		final String temp = hql.toString();
		return hibernateTemplate.execute(new HibernateCallback() {

			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(temp);
				query.setMaxResults(1);				
				return query.uniqueResult();
			}
		});
	}	
	
	/**
     * 根据对象保存.
     * @param obj 对象
     * @return Integer 主键值
     */
	protected Integer saveObject(Object obj)
	{
		String serialNo = hibernateTemplate.save(obj).toString();
		return Utility.parseInt(serialNo);
	}
	
	/**
     * 根据对象更新
     * @param obj 对象
     */
	protected void updateObject(Object obj)
	{
		hibernateTemplate.update(obj);
	}
	
	/**
     * 根据HQL更新
     * @param hql 更新的HQL语句
     * @param objs 参数值列表
     */
	protected void updateObject(String hql,Object[] objs)
	{
		final String temp = hql.toString();
		final Object[] params = objs;
		hibernateTemplate.execute(new HibernateCallback() {

			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(temp);
				for(int i=0;i<params.length;i++)
		        {
		        	query.setParameter(i, params[i]);	        	
		        }
		        query.executeUpdate();   			
				return null;
			}
		});
	}	
	
	
	/**
     * 根据对象删除
     * @param obj
     */
	protected void deleteObject(Object obj)
	{
		hibernateTemplate.delete(obj);
	}
	
	/**
     * 根据主键名删除
     * @param idenityName 主键名称
     * @param className 类名
     * @param id 主键值
     */
	protected void deleteObject(String className,String idenityName,Integer id)
	{
		StringBuilder hql = new StringBuilder("delete from ");
		hql.append(className);
		hql.append(" where ");
		hql.append(idenityName);
		hql.append("=");
		hql.append(id);
        hibernateTemplate.bulkUpdate(hql.toString());
//		final String temp = hql.toString();
//		hibernateTemplate.execute(new HibernateCallback() {
//
//			public Object doInHibernate(Session session)
//					throws HibernateException, SQLException {
//				Query query = session.createQuery(temp);
//				query.executeUpdate();
//				return null;
//			}
//		});
	}
	
	/**
     * 通过ID删除多个对象.
     * @param ids
     * @param idenityName
     * @param className
     * @throws DBException
     */
	protected void deleteObjects(String className,String idenityName,String ids)
	{
		StringBuilder hql = new StringBuilder("delete from ");
		hql.append(className);
		hql.append(" where ");
		hql.append(idenityName);
		hql.append(" in(");
		hql.append(ids);
		hql.append(")");
		
		final String temp = hql.toString();
		hibernateTemplate.execute(new HibernateCallback() {

			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(temp);
				query.executeUpdate();
				return null;
			}
		});
	}
	
	/**
     * Hibernate查询.
     * @param listHql 查询的HQL语句
     * @return
     */
	protected List listAll(String listHql)
	{
		return hibernateTemplate.find(listHql);
	}
	
	/**
     * Hibernate查询.
     * @param className 类名
     * @return
     */
	protected List listAll(Class className)
	{
		return hibernateTemplate.find(" from "+className.getName());		
	}	
	
    
    
	/**
     * Hibernate分页查询.
     * @param pageIndex 当前页码
     * @param listHql 查询的HQL语句
     * @param pageSize 每页显示数
     * @return
     */
	protected List listByHql(String listHql,int pageIndex,int pageSize)
	{		
		int startRow = pageSize * pageIndex - pageSize;
        final String fHql = listHql;
        final int fStartRow = startRow;
        final int fPageSize = pageSize;
        
        return  hibernateTemplate.executeFind( new  HibernateCallback(){
            public  Object doInHibernate(Session session)  throws  SQLException,
                   HibernateException {
              Query q  =  session.createQuery(fHql);
              q.setFirstResult(fStartRow);
              q.setMaxResults(fPageSize);
               return  q.list();
              }
       });      
	}
	
    /**
     * 查询结果集大小.
     * @param listCountHql 查询记录数的HQL
     * @return
     */
	protected int listHqlCount(String listCountHql)
	{
		int count = 0;
        List list = hibernateTemplate.find(listCountHql);
        if(list!=null&&list.size()>0)
        	count = Integer.valueOf(list.get(0).toString());
        return count;
	}
    
    /**
     * Hibernate分页查询.
     * @param pageIndex 当前页码
     * @param pageSize 每页显示数
     * @param listHql 查询的HQL语句
     * @param listCountHql 查询记录数的HQL
     * @return
     */
    protected IPageList listHqlPage(String listHql,String listCountHql,int pageIndex,int pageSize)
    {
        int totalSize = listHqlCount(listCountHql);
        IPageList page = new HibernatePageList();
        page.setPageIndex(pageIndex);
        page.setPageSize(pageSize);
        page.setTotalSize(totalSize);   //该方法将计算pageIndex是否超出最大页数
        page.setRsList(listByHql(listHql,page.getPageIndex(),pageSize));
        return page;
    }
    

    /* ************************* 封装的JDBC操作 ******************************** */  
 
    /**
     * JDBC查询.
     * @param listSql 查询SQL语句
     * @return List
     */
    protected List listBySql(String listSql)
    {
        return jdbcTemplate.queryForList(listSql);
    }
    
	/**
     * JDBC分页查询.
     * @param pageIndex 页码
     * @param listSql 查询SQL语句
     * @param pageSize 每页显示数
     * @return
     */
    protected IPageList listSqlPage(String listSql,int pageIndex,int pageSize)
	{
		if(logger.isDebugEnabled())
		{
			logger.debug("调用的SQL语句 - "+listSql);
		}
        IPageList page = new JdbcPageList();
        page.setPageIndex(pageIndex);
        page.setPageSize(pageSize);    
		page.setRsList(jdbcTemplate.queryForList(listSql));		
		return page;				
	}   
	
	/**
     * 根据SQL语句查询记录数.
     * @param listCountSql 查询记录数的SQL语句
     * @return
     */
    protected int listSqlCount(String listCountSql)
	{
		if(logger.isDebugEnabled())
		{
			logger.debug("调用的SQL语句 - "+listCountSql);
		}
        return jdbcTemplate.queryForInt(listCountSql);
	}

	/**
     * @return
     */
	public HibernateTemplate getHibernateTemplate() {
		return hibernateTemplate;
	}

	/**
     * @param hibernateTemplate
     */
	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}

	/**
     * @return
     */
	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	/**
     * @param jdbcTemplate
     */
	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}	
	

}
